﻿#light
namespace FunctionalStructures

type 'a Queue (front:'a List, rear: 'a List) =
    let frontToBack = match front, rear with Empty, rear -> (rear.Reverse, Empty) | x -> (x)
        
    static member Empty = Queue(List.Empty, List.Empty)
    member this.Snoc value = Queue(front, rear.Cons value)
    member this.Count =  front.Count + rear.Count
        
    member this.Head = 
        match frontToBack with
            | Empty, _ -> failwith "Empty or not reversed"
            | List.Node(a, __), _ -> a

    member this.Tail = 
        match frontToBack with
            |Empty, _ -> failwith "Empty"
            |List.Node(a, tail), r -> Queue(tail, r)
